//============================================================================
// Name        : battle_region.cpp
// Author      : dfoelber
//============================================================================

// INCLUDES //
#include "battle_region.h"
#include "render_manager.h"
#include "image_manager.h"
#include "graphics/graphics.h"
#include "physics/sin_path.h"
#include "draw/SDL_draw.h"
#include "util.h"
#include <iostream>
#include <sstream>
//////////////

using namespace std;

/**
* Constructor
**/
BattleRegion::BattleRegion()
{
	playerHealthPercent = enemyHealthPercent = playerHealth = enemyHealth = totalPlayerHealth = totalEnemyHealth = 0;
	
	Surface* healthSurface = ImageManager::GetManager()->CreateImage(0,0);
	playerHealthBar = new Object(healthSurface, OBJECT_ID_NONE, true);
	
	Surface* enemySurface = ImageManager::GetManager()->CreateImage(0,0);
	enemyHealthBar = new Object(enemySurface, OBJECT_ID_NONE, true);
	
	playerObject = new PlayerObject(ImageManager::GetManager()->GetImage(IMAGE_GOOD_WIZARD_STATIC), false, COLOR_BLUE);
	AddObject(playerObject);
	
	enemyObject = new PlayerObject(ImageManager::GetManager()->GetImage(IMAGE_GOOD_WIZARD_STATIC), true, COLOR_RED);
	AddObject(enemyObject);
}

/**
* Destructor
**/
BattleRegion::~BattleRegion()
{
	if (playerHealthBar)
	{
		delete playerHealthBar;
		playerHealthBar = NULL;
	}
	
	if (enemyHealthBar)
	{
		delete enemyHealthBar;
		enemyHealthBar = NULL;
	}
	
	for( int i = 0; i < (int)playerToCast.size(); i++ )
	{
		delete playerToCast[i];
	}
	
	for( int i = 0; i < (int)animatingEffects.size(); i++ )
	{
		delete animatingEffects[i];
	}
}

/**
* Sets the region's boundary.
* 
* Overridden from Region.
* 
* @param x The boundary's X coordinate
* @param y The boundary's Y coordinate
* @param width The boundary's width
* @param height The boundary's height
**/
void BattleRegion::SetBoundary( int x, int y, int width, int height )
{
	Region::SetBoundary(x, y, width, height);
	
	Color black;
	black.r = black.g = black.b = 0;
	Surface* healthSurface = ImageManager::GetManager()->CreateImage(BAR_WIDTH, height);
	playerHealthBar->GetPath()->SetPosition(x,y);
	Draw_FillRect(healthSurface->GetSurface(), 0, 0, healthSurface->GetWidth(), healthSurface->GetHeight(), 0);
	playerHealthBar->SetSurface(healthSurface, true);
	
	Surface* enemySurface = ImageManager::GetManager()->CreateImage(BAR_WIDTH, height);
	enemyHealthBar->GetPath()->SetPosition(x + width - BAR_WIDTH,y);
	Draw_FillRect(enemySurface->GetSurface(), 0, 0, enemySurface->GetWidth(), enemySurface->GetHeight(), 0);
	enemyHealthBar->SetSurface(enemySurface, true);
	
	playerObject->SetPosition( x + BAR_WIDTH, y + height - playerObject->GetPath()->GetHeight() - 4 );
	enemyObject->SetPosition( x + width - enemyObject->GetPath()->GetWidth() - BAR_WIDTH, y + height - playerObject->GetPath()->GetHeight() - 4 );
}

/**
* Notify the region of an event.
* 
* Overridden from Region.
* 
* @param event The event that happened
* @return If the region used the event
**/
bool BattleRegion::ProcessEvent( SDL_Event event )
{
	return Region::ProcessEvent( event );
}

/**
* Notifies of time passing.
* 
* Overridden from Region.
* 
* @param The amount of time, in milliseconds, that passed since the last call
**/
void BattleRegion::TimePassed( int ms )
{
	for( vector<AnimationObject*>::iterator it = animations.begin(); it < animations.end(); it++ )
	{
		if( !(*it)->IsAnimating() )
		{
			RemoveObject(*it);
			animations.erase(it);
			it = animations.begin() - 1;
		}
	}
	
	bool playerCasting = playerObject->IsCasting();
	bool enemyCasting = enemyObject->IsCasting();
	Region::TimePassed(ms);
	
	for( int i = 0; i < (int)animatingEffects.size(); i++ )
	{
		if( animatingEffects[i]->GetId() == EFFECT_DAMAGE_OVER_TIME )
		{
			DoTEffect* effect = ((DoTEffect*)animatingEffects[i]);
			effect->timeCounter += ms;
			
			if( (effect->timeCounter / 1000) / effect->GetDamage()[effect->level].occur > effect->tickCounter )
			{
				effect->tickCounter++;
				vector<string> target = Util::Split( effect->GetTarget(), ',' );
				if( (int)target.size() > 1 && target[1] == EFFECT_TARGET_ENEMY )
				{
					int damage = effect->GetDamage()[effect->level].damage;
					// TODO: Alignment affecting damage
					enemyHealth -= damage;
				}
				else if( (int)target.size() > 1 && target[1] == EFFECT_TARGET_SELF )
				{
					int damage = effect->GetDamage()[effect->level].damage;
					// TODO: Alignment affecting damage
					playerHealth -= damage;
				}
			}
			
			if( effect->timeCounter >= 
				effect->GetDamage()[effect->level].time * 1000 )
			{
				if( effect->animationObject )
					effect->animationObject->StopAnimating();
			}
		}
		else if( animatingEffects[i]->GetId() == EFFECT_SHIELD )
		{
			ShieldEffect* effect = ((ShieldEffect*)animatingEffects[i]);
			effect->counter += ms;
			
			if( effect->counter > effect->GetDuration() * 1000 )
			{
				if( effect->animationObject )
					effect->animationObject->StopAnimating();
			}
		}
	}
	
	if( playerCasting && !playerObject->IsCasting() )
	{
		if( (int)playerToCast.size() > 0 )
		{
			Effect* effect = playerToCast[0];
			
			playerToCast.erase( playerToCast.begin() );
			
			if( effect->GetAnimation() == EFFECT_ANIMATION_DEFAULT )
			{
				EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_DONE );
			}
			else if( effect->GetAnimation() == EFFECT_ANIMATION_FIREBALL )
			{
				StartFireballAnimation(effect);
			}
			else if( effect->GetAnimation() == EFFECT_ANIMATION_BURN )
			{
				StartBurnAnimation(effect);
			}
			else if( effect->GetAnimation() == EFFECT_ANIMATION_FIRE_SHIELD )
			{
				StartFireShieldAnimation(effect);
			}
			
			if( (int)playerToCast.size() > 0 )
			{
				playerObject->StartCastAnimation();
				
				AnimationObject* animation = new AnimationObject();
				AddObject(animation);
				animation->SetAnimationImages(ImageManager::GetManager()->GetPlayerRedBuildupAnimation(), false, false, AnimationObject::DURATION_ONCE);
				animation->SetPosition(playerObject->GetPath()->GetX(),playerObject->GetPath()->GetY());
				animations.push_back(animation);
			}
		}
	}
	else if( enemyCasting && !enemyObject->IsCasting() )
	{
		if( (int)enemyToCast.size() > 0 )
		{
			Effect* effect = enemyToCast[0];
			
			enemyToCast.erase( enemyToCast.begin() );
			
			if( effect->GetAnimation() == EFFECT_ANIMATION_DEFAULT )
			{
				EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_DONE );
			}
			else if( effect->GetAnimation() == EFFECT_ANIMATION_FIREBALL )
			{
				EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_STARTED );
				StartFireballAnimation(effect);
			}
			else if( effect->GetAnimation() == EFFECT_ANIMATION_BURN )
			{
				EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_STARTED );
				StartBurnAnimation(effect);
			}
			else if( effect->GetAnimation() == EFFECT_ANIMATION_FIRE_SHIELD )
			{
				EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_STARTED );
				StartFireShieldAnimation(effect);
			}
			
			if( (int)enemyToCast.size() > 0 )
			{
				enemyObject->StartCastAnimation();
				
				AnimationObject* animation = new AnimationObject();
				AddObject(animation);
				animation->SetAnimationImages(ImageManager::GetManager()->GetEnemyRedBuildupAnimation(), false, false, AnimationObject::DURATION_ONCE);
				animation->SetPosition(enemyObject->GetPath()->GetX(),playerObject->GetPath()->GetY());
				animations.push_back(animation);
			}
		}
	}
	
	// clean up
	for( vector<Effect*>::iterator it = animatingEffects.begin(); it < animatingEffects.end(); it++ )
	{
		Effect* effect = *it;
		if( effect->animationObject != NULL && !(effect->animationObject->IsAnimating()) )
		{
			RemoveObject(effect->animationObject);
			effect->animationObject = NULL;
			animatingEffects.erase(it);
			
			EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_DONE );
			
			it = animatingEffects.begin() - 1;
		}
	}
	
	// Health Bar
	bool repaint = false;
	if( playerHealthPercent < GetPercentHealth() )
	{
		playerHealthPercent += (double)ms / 20.0;
		if( playerHealthPercent > 100 )
			playerHealthPercent = 100;
		repaint = true;
	}
	if( playerHealthPercent > GetPercentHealth() )
	{
		playerHealthPercent -= (double)ms / 20.0;
		if( playerHealthPercent < 0 )
			playerHealthPercent = 0;
		repaint = true;
	}
	
	if( repaint )
	{
		Color black;
		black.r = black.g = black.b = 0;
		SDL_Rect rect;
		rect.x = 0; rect.y = 0; rect.w = playerHealthBar->GetPath()->GetWidth(); rect.h = playerHealthBar->GetPath()->GetHeight();
		Draw_FillRect(playerHealthBar->GetSurface()->GetSurface(), 0, 0, playerHealthBar->GetPath()->GetWidth(), playerHealthBar->GetPath()->GetHeight(), 0);

		double height = playerHealthBar->GetPath()->GetHeight() * (playerHealthPercent / 100);
		ImageManager::GetManager()->GetImage(IMAGE_PLAYER_HEALTH)->Apply(playerHealthBar->GetSurface(),
				0,
				0,
				playerHealthBar->GetSurface()->GetWidth(),
				(int)height,
				0,
				playerHealthBar->GetPath()->GetHeight() - (int)height);
	}
	
	// Enemy Health Bar
	repaint = false;
	if( enemyHealthPercent < GetPercentEnemyHealth() )
	{
		enemyHealthPercent += (double)ms / 20.0;
		if( enemyHealthPercent > 100 )
			enemyHealthPercent = 100;
		repaint = true;
	}
	if( enemyHealthPercent > GetPercentEnemyHealth() )
	{
		enemyHealthPercent -= (double)ms / 20.0;
		if( enemyHealthPercent < 0 )
			enemyHealthPercent = 0;
		repaint = true;
	}
	
	if( repaint )
	{
		Color black;
		black.r = black.g = black.b = 0;
		SDL_Rect rect;
		rect.x = 0; rect.y = 0; rect.w = enemyHealthBar->GetPath()->GetWidth(); rect.h = enemyHealthBar->GetPath()->GetHeight();
		Draw_FillRect(enemyHealthBar->GetSurface()->GetSurface(), 0, 0, enemyHealthBar->GetPath()->GetWidth(), enemyHealthBar->GetPath()->GetHeight(), 0);

		double height = enemyHealthBar->GetPath()->GetHeight() * (enemyHealthPercent / 100);
		ImageManager::GetManager()->GetImage(IMAGE_PLAYER_HEALTH)->Apply(enemyHealthBar->GetSurface(),
				0,
				0,
				enemyHealthBar->GetSurface()->GetWidth(),
				(int)height,
				0,
				enemyHealthBar->GetPath()->GetHeight() - (int)height);
	}
}

/**
* Renders the objects on the background
* 
* Overridden from Region.
**/
void BattleRegion::Render()
{
}

/**
* An effect's state has changed.
* 
* Overridden from EffectsListener
* 
* @param effect The effect that is updated
**/
void BattleRegion::EffectStateChanged( Effect* effect )
{
	if( effect->state == EFFECT_STATE_READY && effect->GetAnimation() == EFFECT_ANIMATION_NONE )
	{
		EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_DONE );
		return;
	}
	
	if( effect->state == EFFECT_STATE_READY && effect->useCastAnimation )
	{
		if( effect->origin == EFFECT_TARGET_SELF )
		{
			bool contains = false;
			for( int i = 0; i < (int)playerToCast.size(); i++ )
			{
				if( effect->uid == playerToCast[i]->uid )
				{
					contains = true;
					break;
				}
			}
			
			if( !contains )
				playerToCast.push_back( effect );
			
			if( !playerObject->IsCasting() )
			{
				playerObject->StartCastAnimation();
				
				// for testing - build up
				AnimationObject* animation = new AnimationObject();
				AddObject(animation);
				animation->SetAnimationImages(ImageManager::GetManager()->GetPlayerRedBuildupAnimation(), false, false, AnimationObject::DURATION_ONCE);
				animation->SetPosition(playerObject->GetPath()->GetX(),playerObject->GetPath()->GetY());
				animations.push_back(animation);
			}
		}
		else if( effect->origin == EFFECT_TARGET_ENEMY )
		{
			bool contains = false;
			for( int i = 0; i < (int)enemyToCast.size(); i++ )
			{
				if( effect->uid == enemyToCast[i]->uid )
				{
					contains = true;
					break;
				}
			}
			
			if( !contains )
				enemyToCast.push_back( effect );
			
			if( !enemyObject->IsCasting() )
			{
				enemyObject->StartCastAnimation();
				
				// for testing - build up
				AnimationObject* animation = new AnimationObject();
				AddObject(animation);
				animation->SetAnimationImages(ImageManager::GetManager()->GetEnemyRedBuildupAnimation(), false, false, AnimationObject::DURATION_ONCE);
				animation->SetPosition(enemyObject->GetPath()->GetX(),playerObject->GetPath()->GetY());
				animations.push_back(animation);
			}
		}
	}
	else if( effect->state == EFFECT_STATE_READY )
	{
		if( effect->GetAnimation() == EFFECT_ANIMATION_DEFAULT )
		{
			EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_DONE );
		}
		else if( effect->GetAnimation() == EFFECT_ANIMATION_FIREBALL )
		{
			EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_STARTED );
			StartFireballAnimation(effect);
		}
		else if( effect->GetAnimation() == EFFECT_ANIMATION_BURN )
		{
			EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_STARTED );
			StartBurnAnimation(effect);
		}
		else if( effect->GetAnimation() == EFFECT_ANIMATION_FIRE_SHIELD )
		{
			EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_ANIMATION_STARTED );
			StartFireShieldAnimation(effect);
		}
	}
	else if( effect->GetId() == EFFECT_DIRECT_DAMAGE && effect->GetTrigger() == effect->state )
	{
		vector<string> target = Util::Split( effect->GetTarget(), ',' );
		if( (int)target.size() > 1 && target[1] == EFFECT_TARGET_ENEMY )
		{
			int damage = ((DirectDamageEffect*)effect)->GetDamage()[effect->level];
			// TODO: Alignment affecting damage
			enemyHealth -= damage;
		}
		else if( (int)target.size() > 1 && target[1] == EFFECT_TARGET_SELF )
		{
			int damage = ((DirectDamageEffect*)effect)->GetDamage()[effect->level];
			// TODO: Alignment affecting damage
			playerHealth -= damage;
		}
	}
}

/**
* Triggered if an object in the collision list is hit.
* 
* Overridden from Region.
* 
* @param moving The moving that hit the object
* @param hit The object that was hit
**/
void BattleRegion::CollisionListHit(Object* moving, Object* hit)
{
	Effect* hitEffect = NULL;
	
	for( int i = 0; i < (int)animatingEffects.size(); i++ )
	{
		if( animatingEffects[i]->animationObject == hit )
		{
			hitEffect = animatingEffects[i];
		}
	}
	
	if( hitEffect )
	{
		for( int i = 0; i < (int)animatingEffects.size(); i++ )
		{
			if( animatingEffects[i]->animationObject == moving )
			{
				if( hitEffect->GetId() == EFFECT_SHIELD )
				{
					ShieldEffect* effect = (ShieldEffect*)hitEffect;

					if( effect->GetMode() == SHIELD_MODE_REFLECT )
					{
						int x = moving->GetPath()->GetX();
						int y = moving->GetPath()->GetY();
			
						EffectsManager::GetManager()->ReverseTarget(animatingEffects[i]);
							
						Effect* effect = animatingEffects[i];
						RemoveObject(animatingEffects[i]->animationObject);
						animatingEffects[i]->animationObject = NULL;
						animatingEffects.erase( animatingEffects.begin() + i );
						
						if( effect->GetAnimation() == EFFECT_ANIMATION_FIREBALL )
						{
							StartFireballAnimation(effect, x, y);
						}
						else if( effect->GetAnimation() == EFFECT_ANIMATION_BURN )
						{
							StartBurnAnimation(effect);
						}
						else if( effect->GetAnimation() == EFFECT_ANIMATION_FIRE_SHIELD )
						{
							StartFireShieldAnimation(effect);
						}
					}
					else
					{
						Effect* effect = animatingEffects[i];
						
						RemoveObject(animatingEffects[i]->animationObject);
						animatingEffects[i]->animationObject = NULL;
						animatingEffects.erase( animatingEffects.begin() + i );		
						
						EffectsManager::GetManager()->ChangeEffectState( effect, EFFECT_STATE_FINISHED );
					}
				}
				
				return;
			}
		}
	}
}

/**
* Checks for a final override on a collision list check.
* 
* Overridden from Region.
* 
* @param moving The moving object
* @param second The second object
* @return If the collision check should be performed
**/
bool BattleRegion::ShouldCheckCollisionList(Object* moving, Object* second)
{
	Effect* movingEffect = NULL; Effect* secondEffect = NULL;
	for( int i = 0; i < (int)animatingEffects.size(); i++ )
	{
		if( animatingEffects[i]->animationObject == moving )
		{
			movingEffect = animatingEffects[i];
		}
		if( animatingEffects[i]->animationObject == second )
		{
			secondEffect = animatingEffects[i];
		}
	}
	
	if( movingEffect && secondEffect )
	{
		if( movingEffect->origin == EFFECT_TARGET_SELF && secondEffect->origin == EFFECT_TARGET_ENEMY ||
				movingEffect->origin == EFFECT_TARGET_SELF && secondEffect->origin == EFFECT_TARGET_ENEMY_SUPPORT ||
				movingEffect->origin == EFFECT_TARGET_ENEMY && secondEffect->origin == EFFECT_TARGET_SELF ||
				movingEffect->origin == EFFECT_TARGET_ENEMY_SUPPORT && secondEffect->origin == EFFECT_TARGET_SELF )
			return true;
	}
	
	return false;
}

/*
* Calculates the player's health as a percentage.
* 
* @return The player's health.
**/
int BattleRegion::GetPercentHealth()
{
	if( totalPlayerHealth == 0 )
		return 0;
	
	else return (int)(( (double)playerHealth / (double)totalPlayerHealth ) * 100);
}

/*
* Calculates the enemy's health as a percentage.
* 
* @return The enemy's health.
**/
int BattleRegion::GetPercentEnemyHealth()
{
	if( totalEnemyHealth == 0 )
		return 0;
	
	else return (int)(( (double)enemyHealth / (double)totalEnemyHealth ) * 100);
}

/**
* Gets the origin coordinates.
* 
* @param effect The effect to extract the origin.
* @param The origin coordinates
**/
Point BattleRegion::GetOriginCoords(Effect* effect)
{
	Point point; point.x = point.y = -1;
	
	if( effect->origin == EFFECT_TARGET_SELF )
	{
		point.x = playerObject->GetPath()->GetX();
		point.y = playerObject->GetPath()->GetY();
	}
	if( effect->origin == EFFECT_TARGET_ENEMY )
	{
		point.x = enemyObject->GetPath()->GetX();
		point.y = enemyObject->GetPath()->GetY();
	}
	
	return point;
}

/**
* Gets the target coordinates.
* 
* @param effect The effect to extract the target.
* @param The target coordinates
**/
Point BattleRegion::GetTargetCoords(Effect* effect)
{
	Point point; point.x = point.y = -1;
	
	if( effect->GetTarget().find(EFFECT_TARGET_ENEMY_SUPPORT) != string::npos )
	{
		// for testing
		point.x = enemyObject->GetPath()->GetX() - 200;
		point.y = enemyObject->GetPath()->GetY();
	}
	else if( effect->GetTarget().find(EFFECT_TARGET_ENEMY) != string::npos )
	{
		point.x = enemyObject->GetPath()->GetX();
		point.y = enemyObject->GetPath()->GetY();
	}
	else if( effect->GetTarget().find(EFFECT_TARGET_SELF) != string::npos )
	{
		point.x = playerObject->GetPath()->GetX();
		point.y = playerObject->GetPath()->GetY();
	}
	
	return point;
}

/**
* Adds object attributes if necessary.
* 
* @param effect The effect.
* @param object The object.
**/
void BattleRegion::AddAttributes(Effect* effect, Object* object)
{
	if( effect->GetId() == EFFECT_SHIELD )
	{
		ShieldEffect* shield = (ShieldEffect*)effect;
		for( int i = 0; i < (int)shield->GetBlockList().size(); i++ )
		{
			object->AddCollisionType( shield->GetBlockList()[i] );
		}
	}
}

/**
* Starts a fireball animation.
* 
* @param effect The effect for the fireball animation.
* @param originX The origin's X (optional)
* @param originX The origin's Y (optional)
**/
void BattleRegion::StartFireballAnimation(Effect* effect, int originX, int originY)
{
	if( originX == -1 && originY == -1 )
	{
		Point point = GetOriginCoords( effect );
		originX = point.x;
		originY = point.y;
	}
	Point target = GetTargetCoords( effect );
	
	bool reversed = false;
	if( effect->origin.find(EFFECT_TARGET_ENEMY_SUPPORT) != string::npos ||
		effect->origin.find(EFFECT_TARGET_ENEMY) != string::npos )
	{
		reversed = true;
	}
	
	// if a valid coordinate
	if( target.x >= 0 && target.y >= 0 && originX >= 0 && originY >= 0 )
	{
		AnimationObject* animation = new AnimationObject();
		animation->SetID( OBJECT_ID_PROJECTILE );
		int apex = (target.x - originX) / 2;
		SinPath* path = new SinPath(originX, originY, target.x, target.y, apex < 0 ? apex * -1 : apex, originY - 40 < 0 ? 0 : originY - 40, 15);
		path->Pause(50);
		animation->SetPath(path);
		AddObject(animation);
		vector<Surface*> fireball;
		fireball.push_back(ImageManager::GetManager()->GetImage(IMAGE_FIREBALL_ANIM_1));
		fireball.push_back(ImageManager::GetManager()->GetImage(IMAGE_FIREBALL_ANIM_2));
		fireball.push_back(ImageManager::GetManager()->GetImage(IMAGE_FIREBALL_ANIM_3));
		fireball.push_back(ImageManager::GetManager()->GetImage(IMAGE_FIREBALL_ANIM_4));
		fireball.push_back(ImageManager::GetManager()->GetImage(IMAGE_FIREBALL_ANIM_5));
		fireball.push_back(ImageManager::GetManager()->GetImage(IMAGE_FIREBALL_ANIM_6));
		animation->SetAnimationImages(fireball, reversed, true, AnimationObject::DURATION_PATH);
		animation->SetPosition(originX,originY);
		effect->animationObject = animation;
		animatingEffects.push_back(effect);
	}
	else
	{
		// abort...
	}
}

/**
* Starts a burn animation.
* 
* @param effect The effect for the burn animation.
**/
void BattleRegion::StartBurnAnimation(Effect* effect)
{
	Point target = GetTargetCoords( effect );
	
	// if a valid coordinate
	if( target.x >= 0 && target.y >= 0 )
	{
		AnimationObject* animation = new AnimationObject();
		AddObject(animation);
		vector<Surface*> burn;
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_1));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_2));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_3));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_4));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_5));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_6));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_7));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_8));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_9));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_10));
		animation->SetAnimationImages(burn, false, false, AnimationObject::DURATION_EXTERNAL);
		animation->SetPosition(target.x,target.y);
		effect->animationObject = animation;
		animatingEffects.push_back(effect);
	}
	else
	{
		// abort...
	}
}

/**
* Starts a fire shield animation.
* 
* @param effect The effect for the fire shield animation.
**/
void BattleRegion::StartFireShieldAnimation(Effect* effect)
{
	Point target = GetOriginCoords( effect );
	if( effect->origin == EFFECT_TARGET_SELF )
	{
		target.x += 40;
		target.y -= 20;
	}
	else if( effect->origin == EFFECT_TARGET_ENEMY )
	{
		target.x -= 40;
		target.y -= 20;
	}
	
	// if a valid coordinate
	if( target.x >= 0 && target.y >= 0 )
	{
		AnimationObject* animation = new AnimationObject();
		AddAttributes(effect, animation);
		AddObject(animation);
		vector<Surface*> burn;
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_1));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_2));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_3));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_4));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_5));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_6));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_7));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_8));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_9));
		burn.push_back(ImageManager::GetManager()->GetImage(IMAGE_BURN_ANIM_10));
		animation->SetAnimationImages(burn, false, false, AnimationObject::DURATION_EXTERNAL);
		animation->SetPosition(target.x,target.y);
		effect->animationObject = animation;
		animatingEffects.push_back(effect);
	}
	else
	{
		// abort...
	}
}
